from django import forms
from django.contrib import messages
from django.core.paginator import Paginator  # 分页实现
from django.http import JsonResponse  # 用于返回JSON响应
from django.shortcuts import render, redirect  # 重定向

from StuApp.models import GradeInfo, ClassInfo, StudentInfo  # 从models中导入这几个数据库的表结构


# 显示班级信息
class ClassForm(forms.ModelForm):
    class_id = forms.CharField(
        label='班级号',  # 设置标签名称
        max_length=3,  # 设置班级号最大长度为3位
        widget=forms.TextInput(attrs={
            'class': 'form-control',  # 为标签增加默认的bootstrap css样式
            'required': True,  # 设置为必填项，数据库定义为unique
            'placeholder': '请输入班级号'
        })
    )
    class_name = forms.CharField(
        label='班级名称',
        max_length=50,
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'required': True,
            'placeholder': '请输入班级名称'
        })
    )
    grade_id = forms.ModelChoiceField(
        label='所属年级',
        queryset=GradeInfo.objects.all(),
        widget=forms.Select(attrs={
            'class': 'form-control',
            'required': True
        })
    )
    student_count = forms.IntegerField(
        label='学生数',
        required=False,
        widget=forms.NumberInput(attrs={
            'class': 'form-control',
            'readonly': True
        })
    )

    class Meta:
        model = ClassInfo
        fields = ['class_id', 'class_name', 'grade_id', 'student_count']


class EditClass(forms.ModelForm):
    """
    编辑班级，与上面的ClassForm类似，使用了两种方法，上面直接是为字段重写，这里直接重写了init方法，为返回的标签循环增加样式
    """
    class_count = forms.IntegerField(
        label='班级学生数',
        required=False,
        disabled=True,
        widget=forms.NumberInput(attrs={
            'class': 'form-control',
            'readonly': True
        })
    )

    class Meta:
        model = ClassInfo
        fields = ['class_id', 'class_name', 'grade_id', 'class_count']

    def __init__(self, *args, **kwargs):
        """
        重写__init__方法，设置表单字段的样式和属性，
        """
        super().__init__(*args, **kwargs)
        for name, field in self.fields.items():
            field.widget.attrs = {"class": 'form-control', "placeholder": field.label}
            if name == 'class_id':
                field.widget.attrs['readonly'] = False  # 设置班级号可修改

        # 设置学生数
        if self.instance.pk:
            self.initial['class_count'] = StudentInfo.objects.filter(student_class=self.instance).count()

    def clean_class_id(self):
        """
        验证班级号是否唯一，如果班级号已存在，则抛出ValidationError
        """
        class_id = self.cleaned_data['class_id']
        if ClassInfo.objects.exclude(pk=self.instance.pk).filter(class_id=class_id).exists():
            raise forms.ValidationError(f'班级号 {class_id} 已存在！')
        return class_id


# 班级列表
def classList(request):
    # 获取所有年级信息
    grades = GradeInfo.objects.all().order_by('grade_id')

    # 获取查询参数
    search_term = request.GET.get('search', '')
    grade_filter = request.GET.get('grade', '')

    # 基础查询
    classes = ClassInfo.objects.all()

    # 应用搜索过滤
    if search_term:
        classes = classes.filter(class_name__icontains=search_term)

    # 应用年级过滤
    if grade_filter:
        classes = classes.filter(grade_id=grade_filter)

    # 按班级号排序
    classes = classes.order_by('class_id')

    # 计算每个班级的学生数
    for class_obj in classes:
        class_obj.student_count = StudentInfo.objects.filter(student_class=class_obj).count()

    # 分页实现
    paginator = Paginator(classes, 10)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)

    context = {
        'classes': page_obj,
        'grades': grades,
        'search_term': search_term,
        'selected_grade': grade_filter,
        'page_obj': page_obj
    }

    return render(request, 'class_info.html', context)


# 添加班级
def addClass(request):
    if request.method == 'POST':
        form = ClassForm(request.POST)
        if form.is_valid():
            class_id = form.cleaned_data['class_id']
            # 检查班级号是否已存在
            if ClassInfo.objects.filter(class_id=class_id).exists():
                messages.error(request, f'班级号 {class_id} 已存在！')
                return render(request, 'add.html', {"form": form, "title": "班级"})

            try:
                # 保存班级信息
                class_obj = form.save()
                messages.success(request, f'班级 {class_obj.class_name} 添加成功！')
                return redirect('class_list')
            except Exception as e:
                messages.error(request, f'添加班级失败：{str(e)}')
                return render(request, 'add.html', {"form": form, "title": "班级"})
        else:
            # 表单验证失败，显示具体的错误信息
            for field, errors in form.errors.items():
                for error in errors:
                    messages.error(request, f'{form.fields[field].label}: {error}')
            return render(request, 'add.html', {"form": form, "title": "班级"})
    else:
        form = ClassForm()
    return render(request, 'add.html', {"form": form, "title": "班级"})


# 修改班级
def updateClass(request, class_id):
    class_obj = ClassInfo.objects.filter(class_id=class_id).first()
    # print(class_obj) 返回queryset对象，[<StuApp.models.ClassInfo: 班级1>]

    if request.method == 'GET':
        form = EditClass(instance=class_obj)
        return render(request, 'edit_layout.html', {
            "form": form,
            "title": "班级",
            "class_obj": class_obj
        })
    elif request.method == 'POST':
        form = EditClass(request.POST, instance=class_obj)

        # 钩子函数检验
        if form.is_valid():
            form.save()
            messages.success(request, '修改成功！')
            return redirect('class_list')

        else:
            messages.error(request, '修改失败！')
            return render(request, 'edit_layout.html', {
                "form": form,
                "title": "班级",
                "class_obj": class_obj
            })


# 删除班级
def deleteClass(request, class_id):
    if request.method == 'POST':
        try:
            class_obj = ClassInfo.objects.get(class_id=class_id)
            class_obj.delete()
            return JsonResponse({'status': 'success'})
        except ClassInfo.DoesNotExist:
            return JsonResponse({'status': 'error', 'message': '班级不存在'})
        except Exception as e:
            return JsonResponse({'status': 'error', 'message': str(e)})
    return JsonResponse({'status': 'error', 'message': '无效的请求方法'})
